using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace MultiplayerServerConnectionHandlers
{
	public class ConnectionHandler : MessageHandler
	{
		public List<UDPMessageBase> unreadMessages = new List<UDPMessageBase>();

		public int myId;

		public GGIPEndPoint receiver;

		public bool isReceiverIdKnown;

		public int receiverId;

		public DateTime lastReceievedMessageTime;

		public double secondsTillDeactivateConnection = 10.0;

		private Coroutine heartbeatsCoroutine;

		public bool isActive
		{
			get
			{
				return isReceiverIdKnown && (DateTime.Now - lastReceievedMessageTime).TotalSeconds < secondsTillDeactivateConnection;
			}
		}

		public ConnectionHandler(GGIPAddress address, int port)
		{
			receiver = new GGIPEndPoint(address, port);
		}

		public override void OnAddedToServer(GGUDPNetworkServer server)
		{
			base.OnAddedToServer(server);
			myId = server.NextClientId();
			heartbeatsCoroutine = server.StartCoroutine(SendHeartbeatEvery(0.25f));
		}

		public override void OnRemovedFromServer(GGUDPNetworkServer server)
		{
			if (heartbeatsCoroutine != null)
			{
				server.StopCoroutine(heartbeatsCoroutine);
			}
			base.OnRemovedFromServer(server);
		}

		public override bool CanAcceptMessage(UDPMessageBase message)
		{
			return message.receiverId == myId && base.CanAcceptMessage(message);
		}

		public override void OnMessageReceived(UDPMessageBase message)
		{
			lastReceievedMessageTime = DateTime.Now;
			isReceiverIdKnown = true;
			receiverId = message.senderId;
			if (message.type == UDPMessageBase.MessageType.ConnectionReject)
			{
				server.RemoveHandler(this);
			}
			else if (message.type != UDPMessageBase.MessageType.HeartbeatMessage)
			{
				unreadMessages.Add(message);
			}
		}

		private IEnumerator SendHeartbeatEvery(float delay)
		{
			while (true)
			{
				if (isReceiverIdKnown)
				{
					if (!isActive)
					{
						break;
					}
					HeartbeatMessage heartbeatMessage = new HeartbeatMessage();
					heartbeatMessage.senderId = myId;
					Send(heartbeatMessage);
				}
				else
				{
					RequestConnectionMessage requestConnectionMessage = new RequestConnectionMessage(myId);
					Debug.Log("ConnectionHandler - RequestConnection");
					server.SendMessage(receiver.Address, receiver.Port, requestConnectionMessage.SerializeToBytes());
				}
				yield return new WaitForSeconds(delay);
			}
			server.RemoveHandler(this);
		}

		public void Send(UDPMessageBase dataMessage)
		{
			dataMessage.senderId = myId;
			dataMessage.receiverId = receiverId;
			server.SendMessage(receiver.Address, receiver.Port, dataMessage.SerializeToBytes());
		}
	}
}
